package com.example.everying.controller.user;/*
 * 项目名称: everything
 * 文件名: WxLoginController
 * 作者: 张泽阳
 * 日期: 2025/5/14
 * 描述:
 */

import com.example.everying.annotation.WebLog;
import com.example.everying.constant.CacheConstants;
import com.example.everying.context.UserContext;
import com.example.everying.model.dto.user.AppWxLoginDto;
import com.example.everying.model.dto.user.VerifyLoginSms;
import com.example.everying.model.dto.user.WxLoginDto;
import com.example.everying.model.dto.user.WxRegisterDto;
import com.example.everying.model.entity.user.UserBindRel;
import com.example.everying.service.content.ActivityArticleService;
import com.example.everying.service.user.UserBindRelService;
import com.example.everying.service.user.WxLoginService;
import com.example.everying.utils.RedisUtils;
import com.example.everying.utils.Result;
import com.example.everying.utils.SmsUtil;
import io.swagger.annotations.Api;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

@Slf4j
@RestController
@Api(tags = "微信登录")
@RequestMapping("/wxlogin")
public class WxLoginController {

    @Autowired
    private WxLoginService wxLoginService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private ActivityArticleService activityArticle;
    @Autowired
    private UserBindRelService userBindRelService;




    @WebLog(description = "微信登录")
    @PostMapping("/login")
    public Result<?> login(@RequestBody WxLoginDto wxLoginDto, HttpServletRequest request) {
/*        if(StringUtils.isEmpty(wxLoginDto.getCode()) || StringUtils.isEmpty(wxLoginDto.getEncryptedData()) || StringUtils.isEmpty(wxLoginDto.getIv())){
            return Result.fail("参数为空");
        }*/
//        System.out.print("code:" + wxLoginDto.getCode());
//        WxLoginVo login = wxLoginService.login(wxLoginDto, request);
//        System.out.print("wxLoginVo:" + login);
//        if (login == null) {
//            return Result.fail("登录失败");
//        }
        return wxLoginService.login(wxLoginDto, request);
    }

    @WebLog(description = "app微信登录")
    @PostMapping("/appWxLogin")
    public Result<?> appLogin(@RequestBody AppWxLoginDto appWxLoginDto) {
        return wxLoginService.appLogin(appWxLoginDto);
    }


    @PostMapping("/validate")
    public Result<?> validateToken(HttpServletRequest request) {
        boolean isTokenValid = wxLoginService.validateToken(request);
        return Result.ok(isTokenValid);
    }


    @WebLog(description = "微信登出")
    @PostMapping("/logout")
    public Result<?> logout() {
        boolean logout = wxLoginService.logout();
        return Result.ok(logout);
    }

    @WebLog(description = "注销账号")
    @PostMapping("/cancelAccount")
    public Result<?> cancelAccount() {
        if (UserContext.getUser() == null) {
            return Result.fail("用户未登录");
        }
        String id = UserContext.getUser().getId();
        log.info("注销账号id:" + id);
        boolean cancelBool = activityArticle.updateByUserID(id);
        if (!cancelBool) {
            return Result.fail("注销失败");
        }
        Boolean flag = wxLoginService.cancelAccount(UserContext.getUser().getId());
        return Result.ok(flag ? "注销成功" : "注销失败");
    }

    @WebLog(description = "用户注册")
    @PostMapping("/register")
    public Result<?> registerByPhone(@RequestBody WxRegisterDto wxRegisterDto){
        return wxLoginService.registerByPhone(wxRegisterDto);
    }

    @WebLog(description = "修改密码" )
    @PostMapping("/updatePassword")
    public Result<?> updatePassword(@RequestBody WxRegisterDto wxRegisterDto) {
        return wxLoginService.updatePassword(wxRegisterDto);
    }
    @WebLog(description = "发送绑定微信验证码")
    @PostMapping("/sms/wxBindSend")
    public Result<?> wxBindSend(@RequestBody WxLoginDto wxLoginDto) {

        // 校验手机号
        if (!isValidChinesePhoneNumber(wxLoginDto.getPhone())) {
            return Result.failMessage(null, "手机号格式错误");
        }
        UserBindRel userBindRel = userBindRelService.getByPhone(wxLoginDto.getPhone());
        if (userBindRel != null){
            return Result.fail("该手机号已绑定微信");
        }
        // 生成6位随机验证码
        String code = String.valueOf(new Random().nextInt(899999) + 100000);

        String key = CacheConstants.SMS_CODE + wxLoginDto.getPhone() + ":" + code;
        // 将验证码存入 Redis，有效期5分钟
        log.info("redid key：{}", key);
        redisUtils.setCacheObject(key, code, 5, TimeUnit.MINUTES);
        SmsUtil.sendMsg(wxLoginDto.getPhone(), code);
        return Result.ok("验证码发送成功");
    }
    @WebLog(description = "发送用户登录验证码")
    @PostMapping("/sms/send")
    public Result<?> sendSms(@RequestBody WxLoginDto wxLoginDto) {

        // 校验手机号
        if (!isValidChinesePhoneNumber(wxLoginDto.getPhone())) {
            return Result.failMessage(null, "手机号格式错误");
        }
        // 生成6位随机验证码
        String code = String.valueOf(new Random().nextInt(899999) + 100000);

        String key = CacheConstants.SMS_CODE + wxLoginDto.getPhone() + ":" + code;
        // 将验证码存入 Redis，有效期5分钟
        log.info("redid key：{}", key);
        redisUtils.setCacheObject(key, code, 5, TimeUnit.MINUTES);
        SmsUtil.sendMsg(wxLoginDto.getPhone(), code);
        return Result.ok("验证码发送成功");
    }

    @WebLog(description = "校验验证码")
    @PostMapping("/sms/verify")
    public Result<?> verifySms(@RequestBody VerifyLoginSms verifyLoginSms){
        String key = CacheConstants.SMS_CODE + verifyLoginSms.getPhone() + ":" + verifyLoginSms.getCode();
        String code = redisUtils.getCacheObject(key);
        if (code == null || !code.equals(verifyLoginSms.getCode())) {
            return Result.fail("验证码错误或已过期");
        }
        return Result.ok("验证码校验成功");
    }

    /**
     * 校验手机号是否合法
     * @param phoneNumber 待校验的手机号
     * @return true-合法 false-不合法
     */
    public static boolean isValidChinesePhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.trim().isEmpty())  {
            return false;
        }

        // 正则表达式匹配中国大陆手机号
        // 1. 以1开头
        // 2. 第二位是3-9的数字
        // 3. 总共11位数字
        String regex = "^1[3-9]\\d{9}$";
        return Pattern.matches(regex,  phoneNumber);
    }
}
